package com.uxsino.simo.query;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.uxsino.commons.utils.config.PropElement;
import com.uxsino.reactorq.model.IndicatorValue;
import com.uxsino.simo.indicator.AGGREGATE_FUNCTION;
import com.uxsino.simo.indicator.CompoundIndicator;
import com.uxsino.simo.indicator.ListAggregateFunction;
import com.uxsino.simo.utils.ConfigLoadingContext;

public class AggrQueryCombine extends QueryCombine<CompoundIndicator, Map<String, Object>> {

    public AggrQueryCombine(CompoundIndicator resultIndicator) {
        super(resultIndicator);
    }

    private ListAggregateFunction innerFunc = new ListAggregateFunction();

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> apply(QueryContext ctxt, List<IndicatorValue> lists) {
        ArrayList<Map<String, Object>> ml = new ArrayList<>();

        for (IndicatorValue iv : lists) {
            if (iv.value != null) {
                ml.addAll((List<Map<String, Object>>) iv.value);
            }
        }
        return innerFunc.apply(ml);
    }

    @Override
    public void loadProp(PropElement eCombine, ConfigLoadingContext lctxt) {
        PropElement eFields = eCombine.getFirstElement("fields");

        if (eFields == null) {
            lctxt.error(eCombine.getSourceLocation(), "fields not found.");
            return;
        }

        for (PropElement efld : eFields.getElements("field")) {
            String srcField = efld.getProp("from").trim();
            String resultField = efld.getProp("to").trim();
            String funcName = efld.getProp("function").toUpperCase().trim();

            if (StringUtils.isEmpty(srcField) || StringUtils.isEmpty(resultField) || StringUtils.isEmpty(funcName)) {
                lctxt.error(efld.getSourceLocation(), "field format wrong.");
                continue;
            }

            AGGREGATE_FUNCTION func;
            try {
                func = AGGREGATE_FUNCTION.valueOf(funcName);
            } catch (Exception e) {
                lctxt.error(efld.getSourceLocation(), "unknown function name.{}", funcName);
                continue;
            }

            innerFunc.addField(srcField, resultField, func);
        }
    }

    @Override
    public boolean isCustom() {
        return false;
    }

}
